// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "AbilitySystemInterface.h"
#include "ModularGameState.h"

#include "LyraGameState.generated.h"

#define UE_API LYRAGAME_API

struct FLyraVerbMessage; // 前向声明

class APlayerState;
class UAbilitySystemComponent;
class ULyraAbilitySystemComponent;
class ULyraExperienceManagerComponent;
class UObject;
struct FFrame;

/**
 * Lyra游戏状态基类
 *
 *	此项目使用的基础游戏状态类。
 */
UCLASS(MinimalAPI, Config = Game)
class ALyraGameState : public AModularGameStateBase, public IAbilitySystemInterface
{
	GENERATED_BODY()

public:

	UE_API ALyraGameState(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get()); // 构造函数

	//~AActor接口
	UE_API virtual void PreInitializeComponents() override; // 预初始化组件
	UE_API virtual void PostInitializeComponents() override; // 后初始化组件
	UE_API virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; // Actor结束游戏时的处理
	UE_API virtual void Tick(float DeltaSeconds) override; // 每帧更新
	//~End of AActor接口

	//~AGameStateBase接口
	UE_API virtual void AddPlayerState(APlayerState* PlayerState) override; // 添加玩家状态
	UE_API virtual void RemovePlayerState(APlayerState* PlayerState) override; // 移除玩家状态
	UE_API virtual void SeamlessTravelTransitionCheckpoint(bool bToTransitionMap) override; // 无缝旅行过渡检查点
	//~End of AGameStateBase接口

	//~IAbilitySystemInterface
	UE_API virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override; // 获取能力系统组件
	//~End of IAbilitySystemInterface

	// 获取用于游戏范围事务的能力系统组件
	UFUNCTION(BlueprintCallable, Category = "Lyra|GameState")
	ULyraAbilitySystemComponent* GetLyraAbilitySystemComponent() const { return AbilitySystemComponent; } // 获取Lyra能力系统组件

	// 发送所有客户端将（可能）收到的消息
	//（仅用于客户端通知，如淘汰、服务器加入消息等...可以处理丢失的情况）
	UFUNCTION(NetMulticast, Unreliable, BlueprintCallable, Category = "Lyra|GameState")
	UE_API void MulticastMessageToClients(const FLyraVerbMessage Message); // 不可靠多播消息到客户端

	// 发送所有客户端将保证收到的消息
	//（仅用于不能处理丢失的客户端通知）
	UFUNCTION(NetMulticast, Reliable, BlueprintCallable, Category = "Lyra|GameState")
	UE_API void MulticastReliableMessageToClients(const FLyraVerbMessage Message); // 可靠多播消息到客户端

	// 获取服务器的FPS，复制到客户端
	UE_API float GetServerFPS() const; // 获取服务器FPS

	// 指示本地玩家状态正在录制回放
	UE_API void SetRecorderPlayerState(APlayerState* NewPlayerState); // 设置录制器玩家状态

	// 获取录制回放的玩家状态，如果有效
	UE_API APlayerState* GetRecorderPlayerState() const; // 获取录制器玩家状态

	// 回放玩家状态更改时调用的委托
	DECLARE_MULTICAST_DELEGATE_OneParam(FOnRecorderPlayerStateChanged, APlayerState*); // 录制器玩家状态更改委托
	FOnRecorderPlayerStateChanged OnRecorderPlayerStateChangedEvent; // 录制器玩家状态更改事件

private:
	// 处理加载和管理当前游戏玩法经验的组件
	UPROPERTY()
	TObjectPtr<ULyraExperienceManagerComponent> ExperienceManagerComponent; // 经验管理器组件

	// 用于游戏范围事务的能力系统组件子对象（主要是游戏提示）
	UPROPERTY(VisibleAnywhere, Category = "Lyra|GameState")
	TObjectPtr<ULyraAbilitySystemComponent> AbilitySystemComponent; // 能力系统组件

protected:
	UPROPERTY(Replicated)
	float ServerFPS; // 服务器FPS

	// 录制回放的玩家状态，用于选择正确的Pawn进行跟随
	// 这仅在回放流中设置，通常不复制
	UPROPERTY(Transient, ReplicatedUsing = OnRep_RecorderPlayerState)
	TObjectPtr<APlayerState> RecorderPlayerState; // 录制器玩家状态

	UFUNCTION()
	UE_API void OnRep_RecorderPlayerState(); // 录制器玩家状态复制回调

};

#undef UE_API